import { Component, Injector } from '@angular/core';
import { AppComponentBase } from '@abp/components';
import {
  ColumnInfoServiceProxy,
  TreeColumnDataColumnType,
  PagedResultDtoOfTreeColumnData,
  TreeColumnData,
  SwitchEntityInputDtoOfInt64,
  GetDataComboItemDtoOfInt64,
} from '@abp/service-proxies/service-proxies';
import * as moment from 'moment';

import { CreateOrEditCloumnComponent } from './create-or-edit-cloumns/create-or-edit-cloumn.component';

@Component({
  templateUrl: './cloumns.component.html',
  styleUrls: ['./cloumns.component.less'],
})
export class CloumnComponent extends AppComponentBase {
  /** 是否显示高级过滤 */
  advancedFiltersVisible = false;
  /** 搜索条件 */
  keyword: string;
  selectedCloumn: GetDataComboItemDtoOfInt64;
  createStartToEndDate = [];
  updateStartToEndDate = [];
  isEnable: boolean = undefined;
  isAuthorize: boolean = undefined;
  expandDataCache = {};

  constructor(
    injector: Injector,
    private columnService: ColumnInfoServiceProxy,
  ) {
    super(injector);
  }

  ngOnInit(): void {
    this.searchData();
  }

  /**
   * 刷新表格数据
   * @param args
   */
  refresh(): void {
    this.searchData();
  }

  dateRangeChange() {
    this.searchData();
  }

  isEnableChange() {
    this.searchData();
  }

  isisAuthorizeChange() {
    this.searchData();
  }

  sort(sort: { key: string; value: string }): void {
    this.tableHelper.sort = sort;
    this.searchData();
  }

  searchData(reset: boolean = false): void {
    if (reset) {
      this.tableHelper.pageIndex = 1;
    }
    this.tableHelper.isLoading = true;

    this.columnService
      .getTreeColumnInfos(
        this.selectedCloumn === undefined
          ? undefined
          : this.selectedCloumn.value,
        this.createStartToEndDate.length === 2
          ? this.createStartToEndDate[0] === null
            ? undefined
            : this.createStartToEndDate[0]
          : undefined,
        this.createStartToEndDate.length === 2
          ? this.createStartToEndDate[1] === null
            ? undefined
            : this.createStartToEndDate[1]
          : undefined,
        this.updateStartToEndDate.length === 2
          ? this.updateStartToEndDate[0] === null
            ? undefined
            : this.updateStartToEndDate[0]
          : undefined,
        this.updateStartToEndDate.length === 2
          ? this.updateStartToEndDate[1] === null
            ? undefined
            : this.updateStartToEndDate[1]
          : undefined,
        this.keyword,
        this.isEnable === null ? undefined : this.isEnable,
        this.isAuthorize === null ? undefined : this.isAuthorize,
        this.tableHelper.getSorting(),
        this.tableHelper.getMaxResultCount(),
        this.tableHelper.getSkipCount(),
      )
      .subscribe(data => {
        this.tableHelper.isLoading = false;
        this.tableHelper.totalRecordsCount = data.totalCount;
        this.tableHelper.records = data.items;
        data.items.forEach(item => {
          this.expandDataCache[item.id] = this.treeToList(item);
        });
      });
  }

  treeToList(root: object): treeNodeInterface[] {
    const stack = [];
    const array = [];
    const hashMap = {};
    stack.push({ ...root, level: 0, expand: false });

    while (stack.length !== 0) {
      const node = stack.pop();
      this.visitNode(node, hashMap, array);
      if (node.childs) {
        for (let i = node.childs.length - 1; i >= 0; i--) {
          stack.push({
            ...node.childs[i],
            level: node.level + 1,
            expand: false,
            parent: node,
          });
        }
      }
    }
    return array;
  }

  collapse(
    array: treeNodeInterface[],
    data: treeNodeInterface,
    $event: boolean,
  ): void {
    if ($event === false) {
      if (data.childs.items) {
        data.childs.items.forEach(d => {
          const target = array.find(a => a.id === d.id);
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  visitNode(
    node: treeNodeInterface,
    hashMap: object,
    array: treeNodeInterface[],
  ): void {
    if (!hashMap[node.id]) {
      hashMap[node.id] = true;
      array.push(node);
    }
  }

  clickIsActiveSwitch(data: TreeColumnData): void {
    const input = new SwitchEntityInputDtoOfInt64();
    input.id = data.id;
    input.switchValue = !data.isActive;
    data.isActive = !data.isActive;
    this.columnService.updateIsActiveSwitchAsync(input).subscribe(result => {
      if (data.isActive) {
        this.notify.success('启用成功!');
      } else {
        this.notify.success('关闭成功!');
      }
    });
  }

  clickIsNeedAuthorizeAccessSwitch(data: TreeColumnData): void {
    const input = new SwitchEntityInputDtoOfInt64();
    input.id = data.id;
    input.switchValue = !data.isNeedAuthorizeAccess;
    data.isNeedAuthorizeAccess = !data.isNeedAuthorizeAccess;
    this.columnService
      .updateIsNeedAuthorizeAccessSwitchAsync(input)
      .subscribe(result => {
        if (data.isActive) {
          this.notify.success('启用成功!');
        } else {
          this.notify.success('关闭成功!');
        }
      });
  }

  createBuildingPlan() {
    let config = this.drawerConfig(
      '添加栏目',
      CreateOrEditCloumnComponent,
      {
        id: undefined,
      },
      500,
    );
    const drawerRef = this.drawerService.create(config);
    drawerRef.afterOpen.subscribe(() => { });
    drawerRef.afterClose.subscribe(data => {
      if (data) {
        this.searchData();
      }
    });
  }

  editBuildingPlan(data: TreeColumnData) {
    let config = this.drawerConfig(
      '编辑栏目' + data.title,
      CreateOrEditCloumnComponent,
      {
        id: data.id,
      },
      500,
    );
    const drawerRef = this.drawerService.create(config);
    drawerRef.afterOpen.subscribe(() => { });
    drawerRef.afterClose.subscribe(data => {
      if (data) {
        this.searchData();
      }
    });
  }

  deleteConfirm(id: number) {
    this.columnService.deleteColumnInfo(id).subscribe(() => {
      this.searchData();
      this.notify.success('删除成功！');
    });
  }

  getColumnTypeText(value: number) {
    return ColumnTypes[value];
  }
}

export interface treeNodeInterface {
  id: number;
  title: string;
  columnType: TreeColumnDataColumnType;
  isActive: boolean;
  isNeedAuthorizeAccess: boolean;
  url: string;
  creationTime: moment.Moment;
  level: number;
  expand: boolean;
  childs?: PagedResultDtoOfTreeColumnData;
}

enum ColumnTypes {
  'Html文本' = 0,
  '图片' = 1,
}
